/**
  ******************************************************************************
  * @file    main.c
  * @author  ashuai0110
  * @version V2.0
  * @date    2024-09-07
  * @brief   使用举例-xmodem
  *
  ******************************************************************************
  * @attention
  *
  * 版权声明:内容为编者(ashuai0110)原创,使用请注明出处,当然,你也可以不这样做^_^
  * 出处链接:https://gitee.com/ashuai0110/mcu_reuse_development_module
  *
  ******************************************************************************
  */

/* 包含头文件-----------------------------------------------------------------*/
#include "bsp.h"

#include "xmodem.h"

/* 私有宏定义-----------------------------------------------------------------*/
#define XMODEM_TX_RX_TEST               (0u) /* 0:测试发送 1:测试接收 */

/* 私有类型定义---------------------------------------------------------------*/

/* 私有变量-------------------------------------------------------------------*/
static xmodem_t xmodem; /* xmodem实例 */
static uint8_t xmodemBuf[XMODEM_BUF_1K_MAX]; /* xmodem数据缓存区 */

/* 全局变量-------------------------------------------------------------------*/

/* 私有函数原型---------------------------------------------------------------*/


/**
  * @brief  This function handles SysTick Handler.
  *
  * @param  None
  *
  * @retval None
  */
void SysTick_Handler(void)
{
    /* 组件计时节拍接口 */
    mw_tick_inc(1);
}

/**
  * @brief  串口1中断
  */
void USART1_IRQHandler(void)
{
    /* 串口1空闲中断 */
    if(USART_GetITStatus(USART1,USART_IT_IDLE) != RESET)
    {
        USART1->SR;
        USART1->DR;
        
        /* 这里写接收处理 */
        xmodem_write_rx_buf(&xmodem, usart1DmaRxBuf, sizeof(usart1DmaRxBuf) - DMA_GetCurrDataCounter(DMA1_Channel5));
        /* dma重配置 */
        bsp_usart1_dma_rx_reconfig(sizeof(usart1DmaRxBuf));
    }
}

/**
  * @brief  串口1接收的dma中断
  */
void DMA1_Channel5_IRQHandler(void)
{
    /* DMA传输完成中断 */
    if(DMA_GetITStatus(DMA1_IT_TC5) != RESET)
    {
        /* 这里写接收处理 */
        xmodem_write_rx_buf(&xmodem, usart1DmaRxBuf, sizeof(usart1DmaRxBuf));
        /* dma重配置 */
        bsp_usart1_dma_rx_reconfig(sizeof(usart1DmaRxBuf));
        
        DMA_ClearITPendingBit(DMA1_IT_TC5);
    }
}

/**
  * @brief  串口1发送的dma中断
  */
void DMA1_Channel4_IRQHandler(void)
{
    static uint16_t num;
    
    /* DMA传输完成中断 */
    if(DMA_GetITStatus(DMA1_IT_TC4) != RESET)
    {
        /* 这里写读取发送内容的处理 */
        num = xmodem_read_tx_buf(&xmodem, usart1DmaTxBuf, sizeof(usart1DmaTxBuf)); /* 读出数据 */
        /* dma重配置 */
        bsp_usart1_dma_tx_reconfig(num);
        
        DMA_ClearITPendingBit(DMA1_IT_TC4);
    }
}

/**
  * @brief  串口发送前准备函数
  * 
  * @param  enState : 0失能 1使能
  *
  * @retval None
  */
void usart1_tx_en(uint8_t enState)
{
    uint16_t num;

    if(enState)
    {
        num = xmodem_read_tx_buf(&xmodem, usart1DmaTxBuf, sizeof(usart1DmaTxBuf)); /* 读出数据 */
        bsp_usart1_dma_tx_reconfig(num); /* dma重配置 */
    }
    else
    {
        DMA_Cmd(DMA1_Channel4, DISABLE);
    }
}

/**
  * @brief  获取xmodem数据包回调函数
  * 
  * @param  packetNum : 数据包序号 首次从1开始 超出255回到0
  *
  * @param  data      : 有效数据缓冲区(需读出数据)
  *
  * @param  len       : 有效数据长度(包含填充内容0x1A)
  *
  * @retval None
  */
void xmodem_get_packet_callback(uint8_t packetNum, uint8_t *data, uint16_t *len)
{
    uint16_t lenTmp = *len;

    MW_PRINT_FUNC("xmodem packet num:%d, len:%d, data: ", packetNum, lenTmp);
    for(uint16_t i = 0; i < lenTmp; i++)
    {
        MW_PRINT_FUNC("%02X ", data[i]);
    }
    MW_PRINT_FUNC("\r\n");
}

/**
  * @brief  设置xmodem数据包回调函数
  * 
  * @param  packetNum : 数据包序号 首次从1开始 超出255回到0
  *
  * @param  data      : 有效数据存放区(需填充数据)
  *
  * @param  len       : 有效数据长度(不包含填充内容0x1A,组件自动填充)
  *
  * @retval None
  */
void xmodem_set_packet_callback(uint8_t packetNum, uint8_t *data, uint16_t *len)
{
    static uint16_t totalSize = 5000; /* 发送数量byte */
    /* 用户自行计算数据量并在发送完全后给len赋值0 */
    *len = (totalSize >= XMODEM_DATA_1K_SIZE) ? XMODEM_DATA_1K_SIZE : totalSize;
    memset((void *)data, packetNum + 'A', *len);
    totalSize -= *len;
}

/**
  * @brief  main
  */
int main(int argc, char *argv[])
{
    MW_VER_LOG("example-xmodem", 2, 0, 0);
    
    /* BSP初始化 */
    bsp_init();

    /* xmodem组件初始化 超时时间1000ms 重发次数2次 */
    xmodem_init(&xmodem, xmodemBuf, sizeof(xmodemBuf), usart1_tx_en, xmodem_get_packet_callback, xmodem_set_packet_callback, 1000, 2);
#if XMODEM_TX_RX_TEST
    /* 启动xmodem接收 */
    xmodem_rx_start(&xmodem, XMODEM_RX_FLAG_CRC);
#endif
    
    while(1)
    {
        static uint8_t ret;
#if XMODEM_TX_RX_TEST
        ret = xmodem_rx_poll(&xmodem); /* xmodem接收轮询处理 */
        if(MW_RET_OK == ret)
        {
            MW_DEBUG_LOG("xmodem rx success");
        }
        else if(MW_RET_ERR == ret)
        {
            MW_DEBUG_LOG("xmodem rx failed");
        }
        else if(MW_RET_TIMEOUT == ret)
        {
            MW_DEBUG_LOG("xmodem rx timeout");
        }
#else
        ret = xmodem_tx_poll(&xmodem); /* xmodem发送轮询处理 */
        if(MW_RET_OK == ret)
        {
            MW_DEBUG_LOG("xmodem tx success");
        }
        else if(MW_RET_ERR == ret)
        {
            MW_DEBUG_LOG("xmodem tx failed");
        }
        else if(MW_RET_TIMEOUT == ret)
        {
            MW_DEBUG_LOG("xmodem tx timeout");
        }
#endif
    }
}

